#include "header.h"

extern LogFile *logFile;
extern LogFile *mainLogFile;
extern pthread_mutex_t LogFileLock;
extern std::map<uint16_t, int> statusNeighborNodes;

extern bool StatusFileOpen ;



Header createHeader(uint8_t messageType, unsigned int dataLength)								// Header msg func
{
	Header header;
	unsigned char *uoid = (unsigned char *) malloc (20 *sizeof(char));
	
	// code taken from the slide
	char obj_type[20];
	memset(obj_type,'\0',20*sizeof(char));
	strncpy(obj_type,"msg",20);
	obj_type[strlen(obj_type)+1] = '\0';
	
	GetUOID(node.getNodeInstanceID(),obj_type,uoid,20);
	

	header.messageType = messageType;
	header.uoid = uoid;
	header.ttl = node.getTTL();
	header.reserved = 0;
	header.dataLength = dataLength;

	return header;
}


HelloMessage sendHello()															// Hello Message func
{
	HelloMessage helloMsg;

    helloMsg.port = node.getPort();
    helloMsg.hostname = node.getHostName();

    return helloMsg;
}

JoinRequestMessage sendJoinRequest()
{
	JoinRequestMessage joinRqstMsg;
	
	joinRqstMsg.location = node.getLocation();
	joinRqstMsg.hostname = node.getHostName();
	joinRqstMsg.port = node.getPort();

	return joinRqstMsg;
}

JoinResponseMessage sendJoinReponse(unsigned char* senderuoid, uint32_t distance)
{	
	JoinResponseMessage joinRpseMsg;

	joinRpseMsg.uoid = senderuoid;
	joinRpseMsg.distance = distance;
	joinRpseMsg.port = node.getPort();
	joinRpseMsg.hostname = node.getHostName();

	return joinRpseMsg;
}

CheckResponseMessage sendCheckResponse(unsigned char* senderuoid)
{	
	CheckResponseMessage checkRpseMsg;
	checkRpseMsg.uoid = senderuoid;
	return checkRpseMsg;
}

StatusResponseMessage sendStatusResponse(unsigned char* senderuoid, char* myData,int recordLengthIndex)
{	
	StatusResponseMessage statusRpseMsg;
	statusRpseMsg.uoid = senderuoid;
	statusRpseMsg.hostInfoLength =  strlen(node.getHostName()) + sizeof(uint16_t);
	statusRpseMsg.port = node.getPort();
	statusRpseMsg.hostname = node.getHostName();
	//	printf("hhehehheheh\n");
statusRpseMsg.data = myData;
	//memcpy(statusRpseMsg.data,myData,recordLengthIndex);
	//printf("--------%x-%x-%x-%x-\n",statusRpseMsg.data[0],statusRpseMsg.data[1],statusRpseMsg.data[2],statusRpseMsg.data[3]);
	return statusRpseMsg;
}


void GetUOID(char *node_inst_id, char *obj_type, unsigned char *uoid_buf, unsigned int uoid_buf_sz)
{
	static unsigned long seq_no=(unsigned long)1;
    char sha1_buf[SHA_DIGEST_LENGTH], str_buf[104];
    snprintf(str_buf, sizeof(str_buf), "%s_%s_%1ld",node_inst_id, obj_type, (long)seq_no++);
    SHA1((unsigned char*)str_buf, strlen(str_buf), (unsigned char*)sha1_buf);
    memset(uoid_buf, 0, uoid_buf_sz);
    memcpy(uoid_buf, sha1_buf,min(uoid_buf_sz,sizeof(sha1_buf)));

}

void printUOID(unsigned char *uoid)
{
	//printf("UOID = ");
	for(int i=0; i <20 ; i++)
	{
		//printf("%x", uoid[i]);
	}
	//printf("\n");
}



//*********************************************************JOIN****************************************************************************

//void JoinToTheNetwork(bool freshStartFlag)															
void JoinToTheNetwork()															
{
	while(1)
	{
		//sleep(2);
		//cout<<"*******************************"<<joinToTheNetworkFlag<<"************************"<<endl;
		if(shutdownFlag == true)
		{
			//printf("MAIN WHILE LOOP BREAK\n");
			//printf("CommandLine Thread EXITED\n");
			pthread_cancel(commandLineThread); 
			break;
		}
		if(joinToTheNetworkFlag == true)
		{
			//printf("function called\n");
			pthread_mutex_lock(&ReadQueue);													//APPLY LOCK
			pthread_cond_signal(&condition_var_Read);	
			pthread_mutex_unlock(&ReadQueue);	

			sleep(5);
			joinToTheNetworkFlag = false;				//set flag to false so that it is not called again if flag is not set from somewhere else
			
			if(node.verifyIfInitFileIsPresent() ==1)								//if the file is present mean PARTICIPATING
			{
				
				pthread_t connectJoinThread[node.getInitNeighbors()];
				int iretConnectJoinThread;
			
																							//http://www.daniweb.com/software-development/c/code/216411/reading-a-file-line-by-line
				// read file and extract the string and create a thread	
				int i =0;
				string filename = node.getHomeDir() + "/init_neighbor_list";
				//printf("FILE LOCATION IS %s\n",filename.c_str());
				const char* file1 = filename.c_str();	
				FILE *file = fopen ( file1, "r" );
				if ( file != NULL )
				{
					char line[100];
					while ( fgets(line,100,file) != NULL ) /* read a line */
					{
						//printf("printing from file %s\n",line);
						//char temp[100];
						//memset(temp,'\0',100);
						//memcpy(temp,line,100);
						iretConnectJoinThread = pthread_create(&connectJoinThread[i++],NULL,connectJoin,(void *)line);	//second is hostname_port
						sleep(1);			//sleep for 1 sec so that when there are more than one thread the variable in the 1st thread is not overriden by  the value of second thread
					}
					fclose ( file );
				}
				else
				{
					perror ( file1 ); /* why didn't the file open? */
				}

				
																				// join for all connect threads																											
				
				for(int j=0; j<(int)node.getInitNeighbors(); j++)
				{
					//printf("Joining for thread\n");
					pthread_join(connectJoinThread[j],NULL);
				}
				//printf("ALL CONNECTJOIN THREAD EXITED\n");



				pthread_mutex_lock(&NeighborList);																//Apply LOCK
				int totalNeighbors = node.getNeighborList().size();
				//printf("Number of neighbors = %d\n",totalNeighbors);
				//printf("Min neighbors = %d\n",(int)node.getMinNeighbors());
				pthread_mutex_unlock(&NeighborList);															//Release LOCK


				if( totalNeighbors < (int)node.getMinNeighbors())				// if hello msg is responded by less than minNeighbor then RESTART
				{	
					string str = node.getHomeDir()+"/init_neighbor_list";
					const char* file = str.c_str();
					if( remove(file) != 0 )
					{
						perror("File is not present\n");
					}
					else
					{
						//printf("init_neighbor_list File successfully deleted\n");
					}

					pthread_mutex_lock(&NeighborList);																//Apply LOCK
					
					multimap<string,int>::iterator it;
					multimap<string,int> tempMap = node.getNeighborList();
					for(it=tempMap.begin();it!=tempMap.end();it++)
					{
						node.getRemoveConnectionList().push_back(it->second);
					}

					node.getNeighborList().clear();										// clear the list				
					
					pthread_mutex_unlock(&NeighborList);																//RELEASE LOCK
					
					pthread_mutex_lock(&UoidMap);
					node.getUoidMessageLifeTime().clear();										//clear the map of uoid
					node.getUoidSocketDescripter().clear();								
					pthread_mutex_unlock(&UoidMap);
					
					//JoinToTheNetwork();									// RESTART
					joinToTheNetworkFlag = true;
				}
				else
				{
																										//SERVER THREAD CREATED
																										//DISPATCHER THREAD CREATED
																										//MSG LIFE TIMER THREAD CREATED
																										////AUTOSHUTDOWN TIMER
					iretServerThread = pthread_create(&serverThread, NULL, server, (void *)node.getPort()); 			//http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
					iretDispatcherThread = pthread_create(&dispatcherThread, NULL, dispatcher, NULL); 			//http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
					iretMsgLifeTimerThread = pthread_create(&msgLifeTimerThread, NULL, msgLifeTimer, NULL);


					
				}
					
			}
			else																	//if the file is not present means FRESH START															
			{
				
				int sockDesc = 0;
				bool foundBeaconNode = false;

				while(1)
				{
					
					struct sockaddr_in serverAddr;
					struct hostent *he;

					//sleep(2);
					multimap<string,uint16_t> tempBeacon;
					multimap<string,uint16_t>::iterator ii;
					tempBeacon = node.getBeaconList();

					for( ii=tempBeacon.begin(); ii!=tempBeacon.end(); ii++)
					{      
						//printf("Host Name = %s\n",(*ii).first.c_str());
						//printf("Port = %hu\n",(*ii).second);
						
						//create a socket
						if ((sockDesc = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
						{
							perror("socket failed");
							continue;;
						}
						
						//finding out the correct hostname and port and filling in the array
						memset(&serverAddr, '\0', sizeof(serverAddr));
						serverAddr.sin_family = AF_INET;
						if ((he = gethostbyname((*ii).first.c_str())) == NULL) 
						{
							//printf("Invalid host");
							continue;
						}
						serverAddr.sin_addr = *((struct in_addr *) he->h_addr);
						serverAddr.sin_port = htons((*ii).second);
						
						//connect to beacon node		
						if (connect(sockDesc, (struct sockaddr *) &serverAddr, sizeof(serverAddr))>= 0) 
						{
							//after connection break out of the loop
							foundBeaconNode = true;
							connectBeaconPort = (*ii).second;
							//printf("Connected to Beacon %s with port number %hu\n",(*ii).first.c_str(), (*ii).second);
							break;
						}
						else
						{
							close(sockDesc);
							//printf("Not Connected to Beacon %s with port number %hu\n",(*ii).first.c_str(), (*ii).second);
						}
						if(shutdownFlag == true)
						{
							break;
						}
					}
					if(shutdownFlag == true)
					{
						break;
					}
					if(foundBeaconNode == true)
					{
						break;
					}
				}
				
				
				// found a beacon node to connect to
				if(foundBeaconNode)
				{
																												// SEND JOIN REQUEST HEADER
					unsigned int dataLength = sizeof(uint32_t)+ strlen(node.getHostName()) + sizeof(uint16_t);					// location + port + hostname;
					Header sendHeader = createHeader((uint8_t)joinRequestMessageType, dataLength);						
				
					//printf("Type = 0x%02x\n",sendHeader.messageType);
					//printUOID(sendHeader.uoid);
					//printf("TTL = %hhu\n",sendHeader.ttl);
					//printf("Reserved = %hhu\n",sendHeader.reserved);
					//printf("Datalength = %u\n",sendHeader.dataLength);
					
					char sendheaderBuffer[28];
					memset(sendheaderBuffer,'\0',28);
					memcpy(&sendheaderBuffer[0],&htons(sendHeader.messageType),1);
					memcpy(&sendheaderBuffer[1],sendHeader.uoid,20);
					memcpy(&sendheaderBuffer[21],&htons(sendHeader.ttl),1);
					memcpy(&sendheaderBuffer[22],&htons(sendHeader.reserved),1);
					memcpy(&sendheaderBuffer[23],&htonl(sendHeader.dataLength),4);
					sendheaderBuffer[27] = '\0';
					int sendJoinHeader = send(sockDesc,&sendheaderBuffer,27,0);
					if(sendJoinHeader != 27)
					{
						printf("Header was not completely sent in FUNCTIONS\n");
						close(sockDesc);
						joinToTheNetworkFlag = true;
					}
					//printf("Join Header Sent = %d\n",sendJoinHeader);


											
																											// SEND JOIN REQUEST MESSAGE
				
					JoinRequestMessage joinRequestMsg = sendJoinRequest();
					//printf("Location = %lu\n",joinRequestMsg.location);
					//printf("Port = %hu\n",joinRequestMsg.port);
					//printf("Hostname = %s\n",joinRequestMsg.hostname);
				
					
					char sendMessageBuffer[sendHeader.dataLength+1];
					memset(sendMessageBuffer,'\0',(sendHeader.dataLength+1)*sizeof(char));
					memcpy(&sendMessageBuffer[0],&htons(joinRequestMsg.location),4);
					memcpy(&sendMessageBuffer[4],&htons(joinRequestMsg.port),2);
					memcpy(&sendMessageBuffer[6],&joinRequestMsg.hostname,strlen(joinRequestMsg.hostname));
					sendMessageBuffer[sendHeader.dataLength] = '\0';
					send(sockDesc,&sendMessageBuffer,sendHeader.dataLength,0);		
					//printf("Message Sent\n");

/*
					Messages msg1;
					msg1.Header = (char *)malloc(28*sizeof(char));
					memset(msg1.Header,'\0',28);
					msg1.Data = (char *)malloc(512*sizeof(char));
					memset(msg1.Data,'\0',512);
					memcpy(msg1.Header,&sendheaderBuffer,27);
					memcpy(&msg1.Data[0],&joinRequestMsg.location,4);
					memcpy(&msg1.Data[4],&joinRequestMsg.port,2);
					memcpy(&msg1.Data[6],joinRequestMsg.hostname,13);
					struct timeval t1;
					gettimeofday(&t1, NULL);
					enterLogMessage(msg1,'s',t1);
*/

					
																													
																											// RECEIVE
					struct timeval selectTimeOut;
					selectTimeOut.tv_sec = 5;
					selectTimeOut.tv_usec = 0; 
					


					fd_set readfds;
						
					
					struct timeval joinFirst, joinLast;
					gettimeofday(&joinFirst, NULL);
					
					int rv;
					multimap<uint32_t, string> joinResponse;	
					
					while(1)
					{
						gettimeofday(&joinLast, NULL);

						FD_ZERO(&readfds);
						FD_SET(sockDesc, &readfds);
						
						if ((uint32_t)(joinLast.tv_sec - joinFirst.tv_sec) >= node.getJoinTimeout()) 
						{
							//printf("Join time out took place\n");
							break;
						}
							
						rv = select(sockDesc+1, &readfds, NULL, NULL, &selectTimeOut);

						if (rv == -1) 
						{
							perror("select 2\n"); // error occurred in select()
							close(sockDesc);
							joinToTheNetworkFlag = true;
						}
						
						else if (rv == 0) 
						{
							continue;
						}
						
						else if (errno == EINTR)
						{
							continue;
						}

						Header recHeader;																			// RECEIVE JOIN HEADER

						char recHeaderBuffer[28];
						memset(recHeaderBuffer,'\0',28);
						int recHeaderBytes = recv(sockDesc,&recHeaderBuffer,27,0);
						if(recHeaderBytes != 27)
						{
							printf("Header was not completely received in FUNCTIONS\n");
							close(sockDesc);
							joinToTheNetworkFlag = true;
						}
						recHeaderBuffer[strlen(recHeaderBuffer)+1] = '\0';
						//printf("Header Received\n");
						//printf("Header Received = %x-%x-%x-%x\n",recHeaderBuffer[0],recHeaderBuffer[1],recHeaderBuffer[2],recHeaderBuffer[3]);

						recHeader.uoid = (unsigned char *)malloc(20* sizeof(char));
						memcpy(&recHeader.messageType,&ntohs(recHeaderBuffer[0]),1);
						memcpy(recHeader.uoid,&recHeaderBuffer[1],20);
						memcpy(&recHeader.ttl,&ntohs(recHeaderBuffer[21]),1);
						memcpy(&recHeader.reserved,&ntohs(recHeaderBuffer[22]),1);
						memcpy(&recHeader.dataLength,&ntohl(recHeaderBuffer[23]),4);
									
									
						//printf("Join Response Type Received = 0x%02x\n",recHeader.messageType);
						//printUOID(recHeader.uoid);
						//printf("Join Response TTL Received = %hhu\n",recHeader.ttl);
						//printf("Join Response Reserved Received = %hhu\n",recHeader.reserved);
						//printf("Join Response Datalength Received = %u\n",recHeader.dataLength);
											
						if(recHeader.messageType == joinResponseMessageType)		//joinResponseMessageType=0xfb
						{
																												// RECEIVE JOIN MESSAGE
							JoinResponseMessage recJoin;

							char recMessageBuffer[recHeader.dataLength+1];
							memset(recMessageBuffer,'\0',(recHeader.dataLength+1)*sizeof(char));
							int recMsgBytes = recv(sockDesc,&recMessageBuffer,recHeader.dataLength,0);					
							if(recMsgBytes != (int) recHeader.dataLength)
							{
								printf("Msg was not completely received in FUNCTIONS\n");
								close(sockDesc);
								joinToTheNetworkFlag = true;
							}
							recMessageBuffer[strlen(recMessageBuffer)+1] = '\0';
							//printf("Message Received = %s---\n",recMessageBuffer);
									
							unsigned long int dist;
							uint16_t port;
							recJoin.uoid = (unsigned char *)malloc(20* sizeof(char));
							recJoin.hostname = (char *)malloc((recHeader.dataLength-26)*sizeof(char));
							memcpy(recJoin.uoid, &recMessageBuffer[0],20);
							memcpy(&dist,&recMessageBuffer[20],4);
							memcpy(&port,&recMessageBuffer[24],2);
							memcpy(recJoin.hostname,&recMessageBuffer[26],recHeader.dataLength-26);
										
							//printUOID(recJoin.uoid);
							//printf("Distance = %lu\n",dist);
							//printf("Port = %hu\n",port);
							//printf("hostname = %s\n",recJoin.hostname);

/*
							Messages msg;
							msg.Header = (char *)malloc(28*sizeof(char));
							memset(msg.Header,'\0',28);
							msg.Data = (char *)malloc(512*sizeof(char));
							memset(msg.Data,'\0',512);
							memcpy(msg.Header,&recHeaderBuffer,27);
							memcpy(&msg.Data[0],&recJoin.uoid,20);
							memcpy(&msg.Data[20],&recJoin.distance,4);
							memcpy(&msg.Data[24],&recJoin.port,2);
							memcpy(&msg.Data[26],recJoin.hostname,13);
							struct timeval t;
							gettimeofday(&t, NULL);
							enterLogMessage(msg,'r',t);
*/															
									
							char* hostname_port=(char*)malloc(100*sizeof(char));				
							sprintf(hostname_port,"%s %hu",recJoin.hostname,port);
							//printf("The hostname_port value is %s\n", hostname_port);
								
							joinResponse.insert(pair<uint32_t, string>(dist,hostname_port));	
							//printf("Join Response from %s with distance %lu\n",hostname_port,dist);
						}
						else
						{
							//printf("Error: The data type is not join response.\n");
						}									
					}
					close(sockDesc);																				// close temp connection to beacon node
																								
					if(joinResponse.size() < node.getInitNeighbors())												// if Less then InitNeightbor join response SHUTDOWN
					{
						//printf("Less no of join responses\n");
						//printf("Shutting down...\n");
						
						exit(1);
						//shutdown code
					}
					else
					{
																													//write in init_neighbor_list_file
						string finalpath = node.getHomeDir() + "/init_neighbor_list";
						ofstream fp;
						fp.open(finalpath.c_str());
						if (!fp)
						{
							//printf("Error in reading the file");
													
						}
						
						int totalNeighbours = 0;
						map<uint32_t, string>::iterator ii;
						for(ii= joinResponse.begin(); totalNeighbours < (int)node.getInitNeighbors();ii++,totalNeighbours++)
						{
							fp << (*ii).second << "\n";
						}
						fp.close();

						//JoinToTheNetwork();
						joinToTheNetworkFlag = true;
					}
				}
			}
		}
	}
}

//**************************************************FOR LOG FILE*********************************************************************

void enterLogData(Messages msg)
{
	Header getHeader;
				
	getHeader.uoid = (unsigned char *)malloc(20* sizeof(char));
	memcpy(&getHeader.messageType,&msg.Header[0],1);
	memcpy(getHeader.uoid,&msg.Header[1],20);
	memcpy(&getHeader.ttl,&msg.Header[21],1);
	memcpy(&getHeader.reserved,&msg.Header[22],1);
	memcpy(&getHeader.dataLength,&msg.Header[23],4);
	
	char * messageUOID = (char *) malloc(20 * sizeof(char));

	char * uoid = (char *) malloc(20 * sizeof(char));
	
	if (messageUOID == NULL)
	{
		mainLogFile->WriteFile("Malloc failed");
		exit(1);
	}
	memcpy(uoid,&getHeader.uoid,20);
	
	//printUOID1(uoid);
	char tUOID[6];
	snprintf(tUOID, 5, "%x%x%x%x", uoid[16],uoid[17],uoid[18],uoid[19]);
		
		
	//sprintf(messageUOID, " %x%x%x%x ", uoid[16], uoid[17], uoid[18],uoid[19]);

	mainLogFile->WriteFile(" ");
	
	mainLogFile->WriteFile((uint32_t) getHeader.ttl);
	
	mainLogFile->WriteFile(tUOID);
		
	free(messageUOID);
	free(uoid);
}



void enterLogMessage(Messages msg, char type, struct timeval t) 
{
    pthread_mutex_lock(&LogFileLock);
    
    Header getHeader;
            
    getHeader.uoid = (unsigned char *)malloc(20* sizeof(char));
    memcpy(&getHeader.messageType,&msg.Header[0],1);
    memcpy(getHeader.uoid,&msg.Header[1],20);
    memcpy(&getHeader.ttl,&msg.Header[21],1);
    memcpy(&getHeader.reserved,&msg.Header[22],1);
    memcpy(&getHeader.dataLength,&msg.Header[23],4);
    
    uint32_t distance = 0;
    uint16_t port = 0;
    uint8_t errorcode = -1;
    char *hostname = (char *) malloc (100*sizeof(char));
    char *time = (char *) malloc(512 * sizeof(char));
    char *uoid = (char *) malloc(20 * sizeof(char));
            
    if (time == NULL || uoid == NULL || hostname==NULL)
    {
        mainLogFile->WriteFilen("Error : enterLogMessage() : Malloc failed.");
        exit(1);
    }
    sprintf(time, " %10ld.%03d ", (long int) t.tv_sec, (int) t.tv_usec / 1000);
    //stringstream nodeid;
    string nodeid = "nunki.usc.edu";
    
    stringstream nodeid1;
    
    multimap<string,int> tempMap;
    tempMap = node.getNeighborList();
    multimap<string,int>::iterator ii;
    int foundflagnode =0;
                                    
    int tempSock=0;
    
    mainLogFile->WriteFile("\n");
    mainLogFile->WriteFile(type); //read forward store.
    mainLogFile->WriteFile(time);
    mainLogFile->WriteFile(" ");
    
    for( ii=tempMap.begin(); ii!=tempMap.end(); ii++)
    {                     
        tempSock = (*ii).second;
        if(tempSock==msg.socketDescripter)
        {
            nodeid=(*ii).first;
            foundflagnode = 1;
        
            mainLogFile->WriteFile(nodeid.c_str());
        }
        
        else if (msg.socketDescripter==-1)
        {
            nodeid=(*ii).first;
            foundflagnode = 1;
            
            mainLogFile->WriteFile(nodeid.c_str());            
        
        }
    }    
    
    if(foundflagnode == 0 && (((uint8_t) msg.Header[0] == (uint8_t) joinResponseMessageType)|| ((uint8_t) msg.Header[0] == (uint8_t) joinRequestMessageType)))
    {
        // for join request sent and join response received, the neighbour list would be empty
        nodeid1 << node.getHostName() <<":"<< 11;
        mainLogFile->WriteFile(nodeid1.str());
    }
    
    else if (foundflagnode == 0)
    {
    mainLogFile->WriteFile(nodeid.c_str());
    }

    
        
    char tUOID[6];
    mainLogFile->WriteFile(" ");
    uint8_t statusType;
    
    switch ((uint8_t) msg.Header[0])
    {
    
    case (uint8_t) helloMessageType:
        mainLogFile->WriteFile("HLLO ");
        mainLogFile->WriteFile("15 ");
        enterLogData(msg);
        //get the port
        
        uint16_t portt;
        memcpy(&portt,&msg.Data[0],2);
        mainLogFile->WriteFile(" ");
        mainLogFile->WriteFile((uint32_t) portt);
        mainLogFile->WriteFile(" ");
        mainLogFile->WriteFilen("nunki.usc.edu");
        break;
        
    case (uint8_t) joinRequestMessageType:
        mainLogFile->WriteFile("JNRQ ");
        mainLogFile->WriteFile("15 ");
        enterLogData(msg);
        
        //get the port
        memcpy(&port,&msg.Data[0],sizeof(uint16_t));
        mainLogFile->WriteFile((uint32_t) port);
        mainLogFile->WriteFile(" ");
        mainLogFile->WriteFilen("nunki.usc.edu");
        break;
        
        
    case (uint8_t) joinResponseMessageType:
    
        //uoid + distance + port + hostname
        mainLogFile->WriteFile("JNRS ");
        mainLogFile->WriteFile("41 ");
        enterLogData(msg);
        memcpy(uoid, &msg.Data[0], 20);
        snprintf(tUOID, 5, "%x%x%x%x", uoid[16],uoid[17],uoid[18],uoid[19]);    
        mainLogFile->WriteFile(tUOID);
        mainLogFile->WriteFile(" ");
        memcpy(&distance,&msg.Data[20],4);
        mainLogFile->WriteFile(distance);
            
        //get the port
        memcpy(&port,&msg.Data[23],sizeof(uint16_t));
        mainLogFile->WriteFile((uint32_t) port);
        mainLogFile->WriteFile(" ");
        
        //get the hostname
        mainLogFile->WriteFilen("nunki.usc.edu");
        break;
        
    case (uint8_t) keepAliveMessageType:
        mainLogFile->WriteFile("KPAV ");
        mainLogFile->WriteFile("0 ");
        //enterLogData(msg);
        break;
        
    case (uint8_t) notifyMessageType:
        mainLogFile->WriteFile("NTFY ");
        mainLogFile->WriteFile("1 ");
        enterLogData(msg);
        memcpy(&errorcode,&msg.Data[0],1);
        mainLogFile->WriteFile((uint32_t) errorcode);
        break;
        
    case (uint8_t) checkRequestMessageType:
        mainLogFile->WriteFile("CKRQ ");
        mainLogFile->WriteFile("0 ");
        enterLogData(msg);
        break;
        
    case (uint8_t) checkResponseMessageType:
        mainLogFile->WriteFile("CKRS ");
        mainLogFile->WriteFile("20 ");
        enterLogData(msg);
        memcpy(uoid, &msg.Data[0], 20);
        snprintf(tUOID, 5, "%x%x%x%x", uoid[16],uoid[17],uoid[18],uoid[19]);    
        mainLogFile->WriteFile(tUOID);
        break;
        
    case (uint8_t) statusRequestMessageType:
        mainLogFile->WriteFile("STRQ ");
        mainLogFile->WriteFile("1 ");
        enterLogData(msg);
        memcpy(&statusType,&msg.Data[0],1);
        //mainLogFile->WriteFile((uint32_t)statusType);
        mainLogFile->WriteFile(" 0x01");
        
        break;
        
    case (uint8_t) statusResponseMessageType:
        mainLogFile->WriteFile("STRS ");
        mainLogFile->WriteFile("20 ");
        enterLogData(msg);
        memcpy(uoid, &msg.Data[0], 20);
        snprintf(tUOID, 5, "%x%x%x%x", uoid[16],uoid[17],uoid[18],uoid[19]);    
        mainLogFile->WriteFile(" ");
        mainLogFile->WriteFile(tUOID);
        break;
        
    default:
        mainLogFile->WriteFilen("Error : enterLogMessage() : Garbage message type recieved.");
        break;
        
    }

    free(time);
    free(uoid);
    
    pthread_mutex_unlock(&LogFileLock);
}
